﻿using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Xml.Serialization;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
using System.Xml;

namespace FRW.Serialize
{
    public class Serialize
    {
        public static Object FromBinaryFile(Object objToSerialize, String filename)
        {
            Object obj;
            FileStream fs = new FileStream(filename, FileMode.Open);
            BinaryFormatter bf = new BinaryFormatter();
            obj = bf.Deserialize(fs);
            fs.Close();

            return obj;
        }

        public static void ToBinaryFile(Object objToSerialize, String filename)
        {
            FileStream fs = new FileStream(filename, FileMode.Create);
            BinaryFormatter bf = new BinaryFormatter();
            bf.Serialize(fs, objToSerialize);
            fs.Close();
        }

        public static void ToXMLFile(Object objToserialize, string filename)
        {
            StreamWriter sr = new StreamWriter(filename);
            sr.Write(ToXML(objToserialize));
            sr.Close();
        }

        public static string ToXML(Object objToSerialize)
        {
            XmlSerializer mySerializer = null;
            MemoryStream msSerializedXML = null;
            try
            {
                // Instantiate the Serializer with the type of object that is being deserialized.
                mySerializer = new XmlSerializer(objToSerialize.GetType());

                // Serialize the object to xml
                msSerializedXML = new MemoryStream();
                mySerializer.Serialize(msSerializedXML, objToSerialize);

                // Get XML as string
                string xmlStr = ASCIIEncoding.ASCII.GetString(msSerializedXML.ToArray());
                msSerializedXML.Close();

                if (xmlStr == null || xmlStr.Length == 0)
                {
                    return String.Empty;
                }

                return xmlStr;
            }
            catch (Exception ex)
            {
                throw ex;
            }
            finally
            {
                if (msSerializedXML != null) { msSerializedXML.Close(); }
            }
        }

        public static object FromXMLFile(Object objToserialize, string filename)
        {
            Object obj;

            StreamReader sr = new StreamReader(filename);
            string tempString = sr.ReadToEnd();
            obj = FromXml(tempString, objToserialize);
            sr.Close();

            return obj;
        }

        //Creates an object from an XML string.
        public static object FromXml(string Xml, Object objToSerialize)
        {
            StringReader stringReader;
            XmlSerializer ser;
            object obj;

            try
            {
                // firstly create our xml serialisation object that we will use for deserialization
                ser = new XmlSerializer(objToSerialize.GetType());
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
                return null;
            }

            try
            {
                // info is passed in as a string so we need to feed it though the process using a stringreader
                stringReader = new StringReader(Xml);
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
                return null;
            }

            try
            {
                // now we can finally deserialise to a generic object that can be cast later
                XmlReaderSettings readerSettings = new XmlReaderSettings();

                readerSettings.IgnoreWhitespace = false;

                obj = ser.Deserialize(XmlReader.Create(stringReader,readerSettings));
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
                return null;
            }

            return obj;
        }
    }
}
